package com.lions.client.view.modulepanel;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.lions.client.model.Condition;
import com.lions.client.model.Module;
import com.lions.client.model.Type;
import com.lions.client.view.audio.AudioOutput;
import com.lions.client.view.mappanel.MapPanel;
import com.lions.client.view.popup.MyPopupPanel;

// TODO: Auto-generated Javadoc
/**
 * This class represents the pop-up that occurs when you click the add module
 * button. This pop-up will add a module to the respective list in the
 * modulePanel.
 * 
 * @author Kyle Fink
 * 
 */
public class EditModulePopup extends MyPopupPanel {

	/**
	 * Sets up the pop-up panel for adding modules.
	 * 
	 * @param modP
	 *            ModulePanel
	 * @param map
	 *            MapPanel
	 * @param mod
	 *            the mod
	 */
	public EditModulePopup(final ModulePanel modP, final MapPanel map,
			final Module mod) {
		// setTitle("Module Entry");
		// setSize("100%", "100%");
		// setGlassEnabled(true);
		//
		// setStyleName("popupwrapper");

		// Add CSS to the panel added to the panel added to the pop-up.
		panel.setStyleName("popup");

		module = mod;
		modulePanel = modP;
		mapPanel = map;

		// Add the buttons click handlers and input boxes handlers
		createHandlers();

		// Adds items to the modTypeLB
		populateLB();

		// Adds Module Type Label and Text Box
		modTypeListBox.setSelectedIndex(module.getTypeAsInt());
		panel.setWidget(0, 0, new Label("Module Type:     "));
		panel.setWidget(0, 1, modTypeListBox);

		// Adds & Sets up Module Condition Label and List Box
		conditionBox.setName("condition");
		conditionBox.addItem("USABLE");
		conditionBox.addItem("REPAIRABLE");
		conditionBox.addItem("UNREPAIRABLE");
		conditionBox.setSelectedIndex(module.getConditionAsInt());
		panel.setWidget(1, 0, new Label("Module condition:"));
		panel.setWidget(1, 1, conditionBox);

		// Adds Module Code Label and Text Box
		cb.setText("1-" + codes);
		cb.setStyleName("integerboxstyle");
		cb.addStyleName("integerboxhint");
		cb.setValue(module.getCode());
		panel.setWidget(2, 0, new Label("Module Code:"));
		panel.setWidget(2, 1, cb);

		// Adds Module Required Turns Label and List Box
		tb.setName("turns");
		tb.addItem("0");
		tb.addItem("1");
		tb.addItem("2");
		tb.setSelectedIndex(module.getTurns());
		panel.setWidget(3, 0, new Label("Required Turns:"));
		panel.setWidget(3, 1, tb);

		// Adds Module X Coordinate Label and Text Box
		xb.setText("1-" + mapPanel.getMapWidth());
		xb.setStyleName("integerboxstyle");
		xb.addStyleName("integerboxhint");
		xb.setValue(module.getX());
		panel.setWidget(4, 0, new Label("Module X coordinate:"));
		panel.setWidget(4, 1, xb);

		// Adds Module Y Coordinate Label and Text Box
		yb.setText("1-" + mapPanel.getMapHeight());
		yb.setStyleName("integerboxstyle");
		yb.addStyleName("integerboxhint");
		yb.setValue(module.getY());
		panel.setWidget(5, 0, new Label("Module Y coordinate:"));
		panel.setWidget(5, 1, yb);

		// Adds Submit button to the Panel
		submit.setStyleName("buttonstyle");
		submit.setTitle("Submit Module");

		// Adds Close button to the Panel
		close.setStyleName("buttonstyle");
		close.setTitle(message);

		// Adds Panel to the Pop-Up
		panel.setWidget(6, 0, submit);
		panel.setWidget(6, 1, close);

		// Adds the Panel with buttons and labels to the popup
		setWidget(panel);
	}

	/**
	 * This is where the click handlers are created for the buttons on this
	 * widget.
	 */
	private void createHandlers() {
		submit.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(final ClickEvent event) {
				// TODO Auto-generated method stub
				Module newModule;
				Type type = moduleType(modTypeListBox.getValue(modTypeListBox
						.getSelectedIndex()));
				Condition condition = conditionType(conditionBox
						.getValue(conditionBox.getSelectedIndex()));
				int turns = Integer.parseInt(tb.getValue((tb.getSelectedIndex())));
				if ((cb.getValue() == null) || (yb.getValue() == null)
						|| (xb.getValue() == null)) {
					if (cb.getValue() == null) {
						cb.setStyleName("integerboxerror");
						cb.setText("");
					}
					if (xb.getValue() == null) {
						xb.setStyleName("integerboxerror");
						xb.setText("");
					}
					if (yb.getValue() == null) {
						yb.setStyleName("integerboxerror");
						yb.setText("");
					}
					submit.setStyleName("buttonerror");
					new AudioOutput().playInputError();
				} else {
					int code = cb.getValue();
					int x = xb.getValue();
					int y = yb.getValue();
					if (x >= 100 || x < 0 || y >= 50 || y < 0 || code >= codes
							|| code < 0) {
						submit.setStyleName("buttonerror");
						new AudioOutput().playInputError();
					} else {
						newModule = new Module(type, condition, code, turns, x,
								y, false);
						modulePanel.editModule(module, newModule);
						hide();

					}
				}
			}
		});

		// Close Button Click Handler
		close.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(final ClickEvent event) {
				hide();
			}

		});

		// X Coordinate Focus Handler
		// Clears the initial hint text
		xb.addFocusHandler(new FocusHandler() {
			@Override
			public void onFocus(final FocusEvent event) {
				if (xb.getText().equals("1-" + mapPanel.getMapWidth())) {
					xb.setText("");
					xb.setStyleName("integerboxstyle");
				} else if (xb.getValue() != null) {
					if ((xb.getValue() < 100) && (xb.getValue()) >= 0) {
						xb.setStyleName("integerboxstyle");
						xb.addStyleName("integerboxsuccess");
						submit.setStyleName("buttonstyle");
					} else {
						xb.setStyleName("integerboxerror");
					}
				} else {
					xb.setStyleName("integerboxerror");
				}
			}
		});
		// X Coordinate Typing Handler
		// Checks for errors in input
		xb.addKeyUpHandler(new KeyUpHandler() {
			@Override
			public void onKeyUp(final KeyUpEvent event) {
				if (xb.getValue() != null) {
					int x = xb.getValue();
					if ((x >= 100) || (x < 0)) {
						xb.setStyleName("integerboxerror");
					} else {
						xb.setStyleName("integerboxstyle");
						xb.addStyleName("integerboxsuccess");
						submit.setStyleName("buttonstyle");
					}
				} else {
					xb.setStyleName("integerboxerror");
				}
			}
		});

		// Y Coordinate Focus Handler
		// Clears the initial hint text
		yb.addFocusHandler(new FocusHandler() {
			@Override
			public void onFocus(final FocusEvent event) {
				if (yb.getText().equals("1-" + mapPanel.getMapHeight())) {
					yb.setText("");
					yb.setStyleName("integerboxstyle");
				} else if (yb.getValue() != null) {
					if ((yb.getValue() < 50) && (yb.getValue() >= 0)) {
						yb.setStyleName("integerboxstyle");
						yb.addStyleName("integerboxsuccess");
						submit.setStyleName("buttonstyle");
					} else {
						yb.setStyleName("integerboxerror");
					}
				} else {
					yb.setStyleName("integerboxerror");
				}
			}
		});
		// Y Coordinate Typing Handler
		// Checks for errors in input
		yb.addKeyUpHandler(new KeyUpHandler() {
			@Override
			public void onKeyUp(final KeyUpEvent event) {
				if (yb.getValue() != null) {
					int y = yb.getValue();
					if ((y >= 50) || (y < 0)) {
						yb.setStyleName("integerboxerror");
					} else {
						yb.setStyleName("integerboxstyle");
						yb.addStyleName("integerboxsuccess");
						submit.setStyleName("buttonstyle");
					}
				} else {
					yb.setStyleName("integerboxerror");
				}
			}
		});

		// Code box Focus Handler
		// Clears the initial hint text
		cb.addFocusHandler(new FocusHandler() {
			@Override
			public void onFocus(final FocusEvent event) {
				if (cb.getText().equals("1-" + codes)) {
					cb.setText("");
					cb.setStyleName("integerboxstyle");
				} else if (cb.getValue() != null) {
					if ((cb.getValue() < codes) && (cb.getValue() >= 0)) {
						cb.setStyleName("integerboxstyle");
						cb.addStyleName("integerboxsuccess");
						submit.setStyleName("buttonstyle");
					} else {
						cb.setStyleName("integerboxerror");
					}
				} else {
					cb.setStyleName("integerboxerror");
				}
			}
		});
		// Code Box Typing Handler
		// Checks for errors in input
		cb.addKeyUpHandler(new KeyUpHandler() {
			@Override
			public void onKeyUp(final KeyUpEvent event) {
				if (cb.getValue() != null) {
					int code = cb.getValue();
					if ((code >= codes) || (code < 0)) {
						cb.setStyleName("integerboxerror");
					} else {
						cb.setStyleName("integerboxstyle");
						cb.addStyleName("integerboxsuccess");
						submit.setStyleName("buttonstyle");
					}
				} else {
					cb.setStyleName("integerboxerror");
				}
			}
		});
	}

	/**
	 * Helper method that converts the condition from a string to the ENUM.
	 * 
	 * @param condition
	 *            String
	 * @return ENUM Condition
	 */
	private Condition conditionType(final String condition) {
		Condition conType = Condition.valueOf(condition);
		return conType;
	}

	/**
	 * * Helper method that converts the type from a string to the ENUM.
	 * 
	 * @param type
	 *            String
	 * @return ENUM Condition
	 */
	private Type moduleType(final String type) {
		Type modType = Type.valueOf(type);
		return modType;
	}

	/**
	 * Adds the module types to a list box for selecting.
	 * 
	 */
	private void populateLB() {
		modTypeListBox.addItem("AIRLOCK");
		modTypeListBox.addItem("CANTEEN");
		modTypeListBox.addItem("CONTROL");
		modTypeListBox.addItem("DORMITORY");
		modTypeListBox.addItem("FOOD_WATER_STORAGE");
		modTypeListBox.addItem("GYM");
		modTypeListBox.addItem("MEDICAL");
		modTypeListBox.addItem("PLAIN");
		modTypeListBox.addItem("POWER");
		modTypeListBox.addItem("SANITATION");
	}

	/** The codes. */
	private int codes = 191;

	/** The panel. */
	private FlexTable panel = new FlexTable();

	/** The module. */
	private Module module;

	/** The module panel. */
	private ModulePanel modulePanel;

	/** The map panel. */
	private MapPanel mapPanel;

	/** The close. */
	private Button close = new Button("Close");

	/** The submit. */
	private Button submit = new Button("Submit");

	/** The message. */
	private String message = "Click to Cancel";

	/** The mod type list box. */
	private ListBox modTypeListBox = new ListBox();

	/** The xb. */
	private final SpeechIntegerBox xb = new SpeechIntegerBox();

	/** The yb. */
	private final SpeechIntegerBox yb = new SpeechIntegerBox();

	/** The cb. */
	private final SpeechIntegerBox cb = new SpeechIntegerBox();

	/** The tb. */
	private final ListBox tb = new ListBox();

	/** The condition box. */
	private final ListBox conditionBox = new ListBox();

}